﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace BlogEngine.Contrib.Providers
{
    class RoleGroupConfig
    {
        private XmlDocument _xmlDocument;

        private Dictionary<String, String> _RoleGroupDictionary;
        private Dictionary<String, String> _GroupRoleDictionary;
        private List<String> _Roles;
        public List<String> Roles
        {
            get
            {
                if (_Roles == null)
                {
                    _Roles = new List<string>();
                }
                return _Roles;
            }
        }
        private Dictionary<String, String> GroupRoleDictionary
        {
            get
            {
                if (_GroupRoleDictionary == null)
                {
                    _GroupRoleDictionary = new Dictionary<string, string>();
                }
                return _GroupRoleDictionary;
            }
        }
        private Dictionary<String, String> RoleGroupDictionary
        {
            get
            {
                if (_RoleGroupDictionary == null)
                {
                    _RoleGroupDictionary = new Dictionary<string, string>();
                }
                return _RoleGroupDictionary;
            }
        }

        public RoleGroupConfig()
        {
            initDocument();
        }
        private RoleGroupConfig(String filePath)
        {
            if (File.Exists(filePath))
            {
                _xmlDocument = new XmlDocument();
                _xmlDocument.Load(filePath);
                parseDocument();
            }
            else
            {
                initDocument();
            }
        }
        public static RoleGroupConfig Open(String filePath)
        {
            return new RoleGroupConfig(filePath);
        }

        public void Save(String filePath)
        {
            _xmlDocument.Save(filePath);
        }

        private void parseDocument()
        {
            // parse roles
            XmlNodeList roles = _xmlDocument.GetElementsByTagName("Role");
            foreach (XmlNode role in roles)
            {
                RoleGroupDictionary.Add(role.Attributes["name"].Value, role.Attributes["group"].Value);
                GroupRoleDictionary.Add(role.Attributes["group"].Value, role.Attributes["name"].Value);
                Roles.Add(role.Attributes["name"].Value);
            }
        }

        private void initDocument()
        {
            _xmlDocument = new XmlDocument();
            XmlElement root = _xmlDocument.CreateElement("RoleGroupConfig");
            XmlElement roles = _xmlDocument.CreateElement("Roles");
            root.AppendChild(roles);
            _xmlDocument.AppendChild(root);
            parseDocument();
        }

        public void addMapping(String role, String group)
        {
            RoleGroupDictionary.Add(role, group);
            GroupRoleDictionary.Add(group, role);
            Roles.Add(role);

            // add new entry to xml            
            XmlNode roles = _xmlDocument.GetElementsByTagName("Roles")[0];
            XmlElement newRoleElement = _xmlDocument.CreateElement("Role");
            XmlAttribute nameAttrib = _xmlDocument.CreateAttribute("name");
            nameAttrib.Value = role;
            XmlAttribute groupAttrib = _xmlDocument.CreateAttribute("group");
            groupAttrib.Value = group;
            newRoleElement.Attributes.Append(nameAttrib);
            newRoleElement.Attributes.Append(groupAttrib);
            roles.AppendChild(newRoleElement);
        }

        public String getRole(String group)
        {
            string roleName = String.Empty;
            if (GroupRoleDictionary.ContainsKey(group))
            {
                roleName = GroupRoleDictionary[group];
            }
            return roleName;
        }

        public String getGroup(String role)
        {
            return RoleGroupDictionary[role] ?? String.Empty;
        }
    }
}
